﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Reflection;
using ThreeByte.ActiveDeck.Service;
using ThreeByte.ActiveDeck.Data.UserResponse;
using System.ComponentModel;
using ThreeByte.ActiveDeck.Content;

namespace ThreeByte.ActiveDeck.Config
{
    public class SlideConfig
    {
        protected static readonly XNamespace ns = ServiceConfiguration.NAMESPACE;

        #region Public Properties
       
        public int SlideId { get; private set; }
        public int SlideNumber {
            get {
                return Parent.Presentation.Slides.FindBySlideID(SlideId).SlideNumber;
            }
        }

        public CoreConfig Parent { get; set; }

        public PageConfig this[int i] {
            get {
                return _pageList.Where(p => p.PageId == i).SingleOrDefault();
            }
        }

        public IEnumerable<int> PageIDs {
            get {
                return _pageList.Select(p => p.PageId);
            }
        }

        public int PageCount {
            get {
                return _pageList.Count;
            }
        }

        public IEnumerable<PageConfig> Pages {
            get {
                return _pageList.ToArray();
            }
        }

        #endregion

        private List<PageConfig> _pageList = new List<PageConfig>();

        public SlideConfig(int slideId) {
            SlideId = slideId;
            AddPage(PageConfig.NewDefaultPage());  //Slide config always has atleast one page in it
        }

        protected SlideConfig(XElement node) {
            SlideId = int.Parse(node.Attribute("SlideID").Value);      
        }

        public void AddPage(PageConfig newPage) {
            newPage.ParentSlideConfig = this;
            _pageList.Add(newPage);
        }

        public void AddPageAfter(int pageId, PageConfig newPage) {
            newPage.ParentSlideConfig = this;
            _pageList.Insert(_pageList.IndexOf(this[pageId]) + 1, newPage);
        }

        public void RemovePage(PageConfig page) {
            _pageList.Remove(page);
        }

        public void ReplacePage(PageConfig oldPage, PageConfig newPage) {
            _pageList[_pageList.IndexOf(oldPage)] = newPage;
            newPage.ParentSlideConfig = this;
        }

        public int IndexOf(PageConfig page) {
            return _pageList.IndexOf(page) + 1;
        }

        public bool IsFirstPage(PageConfig page) {
            return (_pageList.IndexOf(page) == 0);
        }

        public bool IsLastPage(PageConfig page) {
            return (_pageList.IndexOf(page) == (_pageList.Count - 1));
        }

        public PageConfig GetPageAfter(PageConfig page) {
            int currentInt = _pageList.IndexOf(page);
            return _pageList[currentInt + 1];
        }

        public PageConfig GetPageBefore(PageConfig page) {
            int currentInt = _pageList.IndexOf(page);
            return _pageList[currentInt - 1];
        }

        public virtual XElement ToXml() {
            XElement node = new XElement(ns + "SlideConfig");
            node.Add(new XAttribute("SlideID", SlideId));

            foreach(PageConfig page in _pageList){
                node.Add(page.ToXml());
            }
     
            return node;
        }


        public static SlideConfig FromXml(XElement node, Dictionary<Guid, GraphicResource> resources) {

            SlideConfig newSlideConfig = new SlideConfig(node);
            foreach(XElement page in node.Elements(ns + "Page")) {
                PageConfig newPage = PageConfig.FromXml(page, resources);
                newSlideConfig.AddPage(newPage);
            }
            
            return newSlideConfig;
        }

        
    }


}
